package dm.ast;

import test.envset.GlobalState;
import test.utility.Randomly;

import java.util.ArrayList;
import java.util.List;

/**
 * select 语句中的集合查询UNION 、 EXCEPT 、MINUS 和 INTERSECT
 */
public class DmUnionQuery extends DmASTNode{

    public List<DmSelect> Selects = null;
    public List<DmDataType> selTypes = null;
    public List<Integer> unionOPs = null;
    public int unionOps = 0;

    public void addUnionOps(int op){
        unionOPs.add(op);
    }

    public void setSelTypes(List<DmDataType> selTypes){
        this.selTypes = selTypes;
    }

    public DmUnionQuery() {
        Selects = new ArrayList<DmSelect>();
        selTypes = new ArrayList<>();
        unionOPs = new ArrayList<>();
    }

    //将生成的子查询加入
    public void addQuery(DmSelect s){
        Selects.add(s);
    }


    public String toSql(){
        StringBuilder sql = new StringBuilder();
        if(Selects.size() == 1){
            sql.append(Selects.get(0).toSql());
            return sql.toString();
        } else {
            sql.append(Selects.get(0).toSql());
            for(int i=1;i<Selects.size();i++){
                sql.append(opToString(unionOPs.get(i-1)) + Selects.get(i).toSql());
            }
            return sql.toString();
        }
    }

    @Override
    public void fill(GlobalState globalState) {
        if(!isCompleted){

            if(Selects.get(0).subClause[DmSelect.INDEX_WITH] != null){
                globalState.setWithFinishFlag(false);
                Selects.get(0).fill(globalState);
                globalState.setWithInitFlag(false);

                for (int i = 1; i < Selects.size(); i++) {
                    Selects.get(i).fill(globalState);
                }

                globalState.setWithInitFlag(true);
                globalState.setWithFinishFlag(true);

            }else{
                for (int i = 0; i < Selects.size(); i++) {
                    Selects.get(i).fill(globalState);
                }
            }

        }
    }

    @Override
    public void setWidt() {
        //集合运算符的宽度
        wid_t = 2 * Selects.size() - 1;
        for (int i = 0; i < Selects.size(); i++) {
            Selects.get(i).setDept();
            wid_t += Selects.get(i).wid_t;
        }
    }

    @Override
    public void setDept() {
        int tmpMaxDept = 1;
        for (int i = 0; i < Selects.size(); i++) {
            Selects.get(i).setDept();
            if(Selects.get(i).dep_t > tmpMaxDept){
                tmpMaxDept = Selects.get(i).dep_t;
            }
        }
        dep_t = tmpMaxDept;
    }

    @Override
    public DmDataType getExpressionType() {
        return null;
    }

    //处理sql错误
    // -4097 | 单行子查询返回多行
    public void fixErr4097(){
        for (int i = 0; i < Selects.size(); i++) {
            Selects.get(i).fixErr4097();
        }
    }

    private static String opToString(int op){
        switch (op){
            case 0:
                return " UNION ";
            case 1:
                return " EXCEPT ";
            case 2:
                return " MINUS ";
            case 3:
                return " INTERSECT ";
            default:
                return " UNION ";
        }
    }
}
